home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpuzzles.3
/
xpuzzles
/
xpuzzles-5.3.1
/
xrubik
/
RubikU.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-05
|
7KB
|
269 lines
/*
# X-BASED RUBIK'S CUBE(tm)
#
# RubikU.c
#
###
#
# Copyright (c) 1994 - 96 David Albert Bagley, bagleyd@hertz.njit.edu
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# This program is distributed in the hope that it will be "playable",
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
*/
/* Undo algorithm */
#include <stdio.h>
#include <stdlib.h>
#include <X11/IntrinsicP.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/CoreP.h>
#include "RubikP.h"
#include "Rubik2dP.h"
#include "Rubik3dP.h"
typedef struct _MoveRecord
{
/* int face, direction, control; */
unsigned short int packed; /* This makes assumptions on the data. */
int position; /* Do not make assumptions on this one. */
} MoveRecord;
typedef struct _MoveStack
{
MoveRecord move;
struct _MoveStack *previous, *next;
} MoveStack;
static MoveStack *currMove, *lastMove, *firstMove;
static int count;
RubikLoc *startLoc[MAXFACES] = {
NULL, NULL, NULL, NULL, NULL, NULL
};
static void InitStack();
static void PushStack();
static void PopStack();
static int EmptyStack();
static void FlushStack();
static void InitStack()
{
if (!(lastMove = (MoveStack *) malloc(sizeof(MoveStack))))
XtError("Not enough memory, exiting.");
if (!(firstMove = (MoveStack *) malloc(sizeof(MoveStack))))
XtError("Not enough memory, exiting.");
firstMove->previous = lastMove->next = NULL;
firstMove->next = lastMove;
lastMove->previous = firstMove;
count = 0;
}
static void PushStack(move)
MoveRecord move;
{
if (!(currMove = (MoveStack *) malloc(sizeof(MoveStack))))
XtError("Not enough memory, exiting.");
lastMove->previous->next = currMove;
currMove->previous = lastMove->previous;
currMove->next = lastMove;
lastMove->previous = currMove;
currMove->move = move;
count++;
}
static void PopStack(move)
MoveRecord *move;
{
*move = lastMove->previous->move;
currMove = lastMove->previous;
lastMove->previous->previous->next = lastMove;
lastMove->previous = lastMove->previous->previous;
(void) free((void *) currMove);
count--;
}
static int EmptyStack()
{
return (lastMove->previous == firstMove);
}
static void FlushStack()
{
while (lastMove->previous != firstMove) {
currMove = lastMove->previous;
lastMove->previous->previous->next = lastMove;
lastMove->previous = lastMove->previous->previous;
(void) free((void *) currMove);
}
count = 0;
}
/**********************************/
void InitMoves()
{
InitStack();
}
static void WriteMove(move, face, position, direction, control)
MoveRecord *move;
int face, position, direction, control;
{
/* move->face = face; move->direction = direction;
move->control = control; */
move->packed = ((control & 0xF) << 8) + ((direction & 0xF) << 4) +
(face & 0xF);
move->position = position;
}
static void ReadMove(face, position, direction, control, move)
int *face, *position, *direction, *control;
MoveRecord move;
{
/* *face = move.face; *direction = move.direction;
*control = move.control; */
*face = move.packed & 0xF;
*direction = (move.packed >> 4) & 0xF;
*control = (move.packed >> 8) & 0xF;
*position = move.position;
}
void PutMove(face, position, direction, control)
int face, position, direction, control;
{
MoveRecord move;
WriteMove(&move, face, position, direction, control);
PushStack(move);
}
void GetMove(face, position, direction, control)
int *face, *position, *direction, *control;
{
MoveRecord move;
PopStack(&move);
ReadMove(face, position, direction, control, move);
}
int MadeMoves()
{
return !EmptyStack();
}
void FlushMoves(w)
RubikWidget w;
{
int face, position;
FlushStack();
for (face = 0; face < MAXFACES; face++)
for (position = 0; position < w->rubik.sizeSize; position++) {
startLoc[face][position].face =
w->rubik.cubeLoc[face][position].face;
startLoc[face][position].rotation =
w->rubik.cubeLoc[face][position].rotation;
}
}
int NumMoves()
{
return count;
}
void ScanMoves(fp, w, moves)
FILE *fp;
RubikWidget w;
int moves;
{
int face, position, direction, control, k;
char c;
for (k = 0; k < moves; k++) {
while ((c = getc(fp)) != EOF && c != SYMBOL);
(void) fscanf(fp, "%d %d %d %d", &face, &position, &direction, &control);
MoveRubik(w, face, position, direction, control);
}
}
void PrintMoves(fp)
FILE *fp;
{
int face, position, direction, control, counter = 0;
currMove = firstMove->next;
(void) fprintf(fp, "moves\tface\tpos\tdir\tcon\n");
while (currMove != lastMove) {
ReadMove(&face, &position, &direction, &control, currMove->move);
(void) fprintf(fp, "%d%c\t%d\t%d\t%d\t%d\n",
++counter, SYMBOL, face, position, direction, control);
currMove = currMove->next;
}
}
void ScanStartPosition(fp, w)
FILE *fp;
RubikWidget w;
{
int face, position, num;
char c;
while ((c = getc(fp)) != EOF && c != SYMBOL);
for (face = 0; face < MAXFACES; face++)
for (position = 0; position < w->rubik.sizeSize; position++) {
(void) fscanf(fp, "%d ", &num);
startLoc[face][position].face = num;
if (w->rubik.orient) {
(void) fscanf(fp, "%d ", &num);
startLoc[face][position].rotation = num;
}
}
}
void PrintStartPosition(fp, w)
FILE *fp;
RubikWidget w;
{
int face, position;
(void) fprintf(fp, "\nstartingPosition%c\n", SYMBOL);
for (face = 0; face < MAXFACES; face++) {
for (position = 0; position < w->rubik.sizeSize; position++) {
(void) fprintf(fp, "%d ", startLoc[face][position].face);
if (w->rubik.orient)
(void) fprintf(fp, "%d ", startLoc[face][position].rotation);
}
(void) fprintf(fp, "\n");
}
}
void SetStartPosition(w)
RubikWidget w;
{
int face, position;
for (face = 0; face < MAXFACES; face++)
for (position = 0; position < w->rubik.sizeSize; position++) {
w->rubik.cubeLoc[face][position].face =
startLoc[face][position].face;
if (w->rubik.orient)
w->rubik.cubeLoc[face][position].rotation =
startLoc[face][position].rotation;
}
DrawAllPolyhedrons(w);
}